package cn.edu.tju.se.auth.controller;

import java.security.Principal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import cn.edu.tju.se.auth.domain.Udr;
import cn.edu.tju.se.auth.domain.User;
import cn.edu.tju.se.auth.service.UserService;

@RestController
@RequestMapping(value="/api")
public class UserController {

	@Autowired
	UserDetailsService userDetailsService;
	@Autowired
	UserService userService;
	
		
	@RequestMapping("/user")
	public User getUser(Principal user) {
		return userService.findByUsername(user.getName());
	}	

    @PreAuthorize("hasRole('ADMIN')")
    @RequestMapping(value = "/users", method = RequestMethod.GET)
    public Page<User> getUsers(@RequestParam(value = "page", defaultValue = "0") int page,
            @RequestParam(value = "size", defaultValue = "15") int size){
    	Sort sort = new Sort(Direction.ASC, "id");
        Pageable pageable = new PageRequest(page, size, sort);
        return userService.findAll(pageable);
    }

    @RequestMapping(value = {"/users","/public/users"} , method = RequestMethod.POST)
    User addUser(@RequestBody User user) {
    	user.setId(null);
    	user.setMyUdr(new HashSet<Udr>());
        return userService.add(user);
    }
    
    @PostAuthorize("returnObject.username == principal.username or hasRole('ROLE_ADMIN')")
    @RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
    public User getUser(@PathVariable Long id) {
        User user =  userService.findOne(id);
        return user;
    }    
    
    @RequestMapping(value = {"/users/username/{username}","/public/users/username/{username}"},method = RequestMethod.GET)
    public Long getUserByUsername(@PathVariable String username) {
        User user =  userService.findByUsername(username);
        if (user == null) {
        	return null;
        } else {
        	return user.getId();
        }
    }
      
    @RequestMapping(value = {"/users/phone/{phone}","/public/users/phone/{phone}"}, method = RequestMethod.GET)
    public Long getUserByPhone(@PathVariable String phone) {
        User user =  userService.findByPhone(phone);
        if (user == null) {
        	return null;
        } else {
        	return user.getId();
        }
    }

    @RequestMapping(value = {"/users/email/{email}","/public/users/email/{email}"}, method = RequestMethod.GET)
    public Long getUserByEmail(@PathVariable String email) {
        User user =  userService.findByEmail(email);
        if (user == null) {
        	return null;
        } else {
        	return user.getId();
        }
    }
    
    @PostAuthorize("#id == principal.id or hasRole('ADMIN')")
    @RequestMapping(value = "/users/{id}", method = RequestMethod.PUT)
    User updateUser(@PathVariable Long id, @RequestBody User updatedUser,Principal user) {
        	updatedUser.setId(id);
        	return userService.update(updatedUser);
       
    }

    @PreAuthorize("hasRole('ADMIN')")
    @RequestMapping(value = "/users/{id}", method = RequestMethod.DELETE)
    User removeUser(@PathVariable Long id,Principal user) {
		User deletedUser = userService.findOne(id);
		userService.delete(id);
		return deletedUser;
    }

}
